home *** CD-ROM | disk | FTP | other *** search
- .386P
- ; DO NOT USE IT, I JUST STARTED CODING, LOTS OF THINGS ARE MISSING!!
-
- code32 segment para public use32
- assume cs:code32, ds:code32
-
- include 386power.inc
- include vdma.inc
- include 386timer.inc
-
- ; XVD SOUNDBLASTER DRIVER
- sb_base dd 0
- sb_irqn dd 7
- sb_dmac dd 1
- sb_type dd 0
-
- ; some useful i/o port offsets from sb_base
- dsp_reset dd 6
- sb_fm dd 8
- sb_fmdata dd 9
- dsp_read dd 0ah
- dsp_write dd 0ch
- dsp_avail dd 0eh
-
- ; dsp commands
- dma8_dac = 14h
- time_constant = 40h
- halt_dma = 0d0h
- cont_dma = 0d4h
- speaker_on = 0d1h
- speaker_off = 0d3h
- dsp_id = 0e0h
- dsp_ver = 0e1h
-
- ; sb_types
- sb_1_5 =1
- sbpro =2
- sb_2_0 =3
-
- sbwrite: ; in: ah = byte to write to dsp , out: eax,edx modified
- mov edx,dsp_write
- sbw: in al,dx
- test al,080h
- jnz sbw
- mov al,ah
- out dx,ax
- ret
-
- sbread: ; edx modified out: al = byte read from dsp
- mov edx,dsp_avail
- sbr: in al,dx
- test al,80h
- jz sbr
- sub dl,4
- in al,dx
- ret
-
- ; DAC 8bit mono DMA allowed frequencies for a plain soundblaster
- ; 4khz ... 23khz
- ; you set the playback frequency sending a time_constant command
- ; and then sending the t_c byte equivalent to the requested frequency
- ;
- ; t_c = 256 - (1000000/frequency)
- ;
- ; then you need to calculate the actual playback frequency you set
- ; (there are rounding errors)
- ;
- ; actual_frequency = 1000000/(256 - t_c)
- ;
-
- setfreq: ; in: eax= requested frequency
- ; out: eax= nearest supported frequency
- push edx
- push ebx
- cmp eax,4000
- jg goodlow
- mov eax,4000
- goodlow: cmp eax,23000
- jl goodhi
- mov eax,23000
- goodhi: xor edx,edx
- mov ebx,eax
- mov eax,1000000
- div ebx
- sub eax,256
- neg eax
- shl eax,16 ; save t_c into upper word
- mov ah,time_constant
- call sbwrite
- shr eax,8 ; t_c into ah
- call sbwrite
- ; now get back the actual playback frequency
- shr eax,8 ; eax == t_c
- mov ebx,256
- xor edx,edx
- sub ebx,eax
- mov eax,1000000
- div ebx
- ; eax = actual frequency
- pop ebx
- pop edx
- ret
-
- sbirq_ack macro
- mov edx,dsp_avail
- in al,dx
- ; sb irq acknowledged , now notify the eoi to the P.I.C.
- endm
-
- sbsound macro
- mov ah,speaker_on
- call sbwrite
- endm
-
- nosbsound macro
- mov ah,speaker_off
- call sbwrite
- endm
-
- no_blast db 'SoundBlaster XSD DRIVER: DSP timeout or 386Timer too fast',CR,LF
- db ' Maybe soundblaster not present or wrong base address',CR,LF,'$'
-
- error_no_blaster:
- mov 386Return,offset no_blast
- jmp _Exit
- ; reset sound blaster dsp
-
- dspreset:
- pushad
- mov edx,dsp_reset
- mov al,01
- out dx,al
- recaliber:
- call _ReadTimer
- lea ebx,[eax+10]
- cmp eax,ebx
- jnb recaliber
- skid3: call _ReadTimer
- cmp eax,ebx
- jb skid3
- mov edx,dsp_reset
- xor al,al
- out dx,al
- xrecaliber:
- call _ReadTimer
- lea ebx,[eax+400]
- cmp eax,ebx
- jnb xrecaliber
- skid100: mov edx,dsp_read
- in al,dx
- cmp al,0AAh
- je gotcha
- call _ReadTimer
- cmp eax,ebx
- jb skid100
- jmp error_no_blaster
- gotcha: popad
- ret
-
- ; ENVIRONMENT SCANNER
- ;
- ; The environment segment is a sequence of ASCIIZ strings
- ; following the format "var=value",0
- ; and terminated by a null string (a single code 0 character)
-
- ENV_SEG= 2ch
- SPACE=32
- TAB=9
-
- envfind: ; in: esi = ptr to ASCIIZ string containing the invironment var. name
- ; out: esi = ptr to ASCIIZ string (by way of the 4GW wraparound)
- ; containing the environment var. "value"
- ; n.b. read it but do not modify it!!!!!!
-
- push edx
- push ebx
- push eax
- mov edx,_PSPBase
- add edx,ENV_SEG
- movzx edx,word ptr gs:[edx]
- shl edx,4
- sub edx,_Code32Base
- estring:
- mov ebx,esi
- eqchar: mov al,[edx]
- cmp al,SPACE
- je skiip
- cmp al,TAB
- je skiip
- cmp al,[ebx]
- jne naah
- inc ebx
- skiip:
- inc edx
- jmp short eqchar
-
- naah: cmp al,'='
- jne findend
- cmp byte ptr [ebx],0
- je cuccato
- findend:
- cmp ebx,esi
- je lafine
- z_end: inc edx
- test al,al
- jz estring
- mov al,[edx]
- jmp short z_end
-
- lafine: test al,al
- jne z_end
- byenv: mov esi,edx
- pop eax
- pop ebx
- pop edx
- cuccato:
- inc edx
- jmp short byenv
-
- ; get BLASTER environment var. settings
-
- sb db 'BLASTER',0 ; ASCIIZ BLASTER
-
- sbenv: pushad
- cmp sb_base,0
- jne env_set
- mov esi, offset sb
- call envfind
- nextc: lodsb
- test al,al
- jz settato
- cmp al,SPACE
- je nextc
- cmp al,TAB
- je nextc
- cmp al,'I'
- jne newa
- lodsb
- sub al,'0'
- mov byte ptr sb_irqn,al
- jmp short nextc
- newa:
- cmp al,'D'
- jne newb
- lodsb
- sub al,'0'
- mov byte ptr sb_dmac,al
- jmp short nextc
- newb:
- cmp al,'T'
- jne newc
- lodsb
- sub al,'0'
- mov byte ptr sb_type,al
- jmp short nextc
- newc:
- cmp al,'A'
- jne nextc ; try to ignore unknown switches
- xor eax,eax
- sboing: lodsb
- cmp al,'0'
- jb sguuk
- cmp al,'9'
- ja sguuk
- sub al,'0'
- skud: shl al,4
- shl eax,4
- jmp short sboing
- sguuk:
- cmp al,'a'
- jb sgook
- cmp al,'f'
- ja sgook
- sub al,'a'
- jmp short skud
- sgook:
- cmp al,'A'
- jb sgok
- cmp al,'F'
- ja sgok
- sub al,'A'
- jmp short skud
- sgok: shr eax,8
- mov sb_base,eax
- jmp short nextc
-
- settato:
- mov eax,sb_base
- test eax,eax
- jz wrong_set
-
-
-
- env_set:
- popad
- ret
-
-